#ifndef BUCKET_H_
#define BUCKET_H_

#include "../../componentes/Bloque.h"

class Directorio;
class Elemento;
class Key;

/*
 * Funcion: Clase que representa el bucket de los registros almacenados
 * para trabajar con hashing extensible.
 */

class Bucket: public Bloque {

	friend class Directorio;

private:
	offset profundidad;
	Directorio* directorio;
	offset nroComponente;
	offset direccion;

public:

	/*
	 * Pre: Argumentos validos.
	 * Pos: crea una nueva instancia.
	 */
	Bucket(cantBytes tamanio, Directorio* directorio, unsigned profundidad = 0);

	/*
	 * Pre: -
	 * Pos: Libera los recursos instanciados.
	 */
	virtual ~Bucket();

	/*
	 * Pre: La clave no exista.
	 * Pos: Agrega el elemento al bucket
	 */
	bool agregar(Elemento &elemento);

	/*
	 * Pre: La clave este contenida en el bucket.
	 * Pos: remueve la clave del bucket.
	 */
	bool remover(Key &clave);

	/*
	 * Pre: clave valida.
	 * Pos: setea el elemento relacionado con la clave.
	 */
	bool obtenerElemento(Key &clave, Elemento &elemento);

	/*
	 * Pre: -
	 * Pos: Serializa el objeto.
	 */
	virtual Bytes serializarse();

	/*
	 * Pre: bytes validos.
	 * Pos: hidrata el estado del objeto.
	 */
	virtual void hidratarse(const Bytes& bytes);

	/*
	 * Pre: -
	 * Pos: divide el bucket.
	 */
	bool dividirse();

	/*
	 * Pre: -
	 * Pos: setea las direcciones del bucket.
	 */
	void direccionesNuevoBucket(offset& inicial, offset& final);

	/*
	 * Pre: -
	 * Pos: devuelve la direccion.
	 */
	virtual offset obtenerDireccion();

	bool tieneHermano();
	offset obtenerDireccionHermano();
	bool combinar();

private:

	/*
	 * Pre: El otro bucket no sea nulo.
	 * Pos: redistribuye el bucket.
	 */
	void redistribuir(Bucket* otroBucket);

	void imprimirClaves();
};

#endif /* BUCKET_H_ */
